using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;

namespace Gameplay.PVE
{
    public class AStarRoadPath : UnitRoadPath
    {
        private int state
        {
            set
            {
                m_state = value;
                BattleLog.UnitLog(unit,"findPathState:" + m_state);
            }
            get { return m_state; }
        }
        private int m_state = 0;

        public delegate bool AStarCondition();

        private AStarCondition condition1;
        private AStarCondition condition2;

        public AStarCondition forceEndCondition;
        
        
        public void SetCondition1Handler(AStarCondition condition)
        {
            condition1 = condition;
        }
        
        public void SetCondition2Handler(AStarCondition condition)
        {
            condition2 = condition;
        }

        public void SetForceEndCondition(AStarCondition condition)
        {
            forceEndCondition = condition;
        }
        
        protected override void Reset()
        {
            base.Reset();
            condition1 = null;
            condition2 = null;
            forceEndCondition = null;
        }

        public override void Init(UnitBase unit)
        {
            unit.Data.hasReachAttackPosition = false;
            base.Init(unit);
            state = 0;
            lastTarget = null;
        }

         public override void OnTransmit(ETransmitType type,BaseTransmitArg arg)
        {
            base.OnTransmit(type,arg);
            if (type == ETransmitType.RePath)
            {
                needRepath = true;
            }
            else if (type == ETransmitType.AttackEnd)
            {
                if (!PveFindPathManager.Instance.CheckIsWalkable(unit.Data.position, unit.Data.id))
                {
                    state = 0;
                    lastRepathTime = 0;
                }
            }
        }
        
        public override void Update()
        {
            base.Update();
            if (PveManager.Instance.rpgStart)
            {
                UpdatePath();
            }
            else
            {
                MoveToTargetPosition(unit.Data.birthPosition);
            }
            
            if (Vector3.Distance(position,unit.Data.position) < 0.01f)
            {
                unit.Data.targetMoveSpeed = 0;
                unit.Data.moveState = 0;
                isFinish = true;
            }
            else
            {
                unit.Data.moveState = 2;
            }
            /*else
            {
                if (!unit.Data.isGoingToHidePoint)
                {
                    unit.Data.RemoveAstar();
                }
            }*/
            
        }

        //阶段0 选择目标点，执行寻路，转为阶段1
        //阶段1 沿着初次寻路的路径走，直到满足条件，进入阶段2
        //阶段2 自己在阻挡点，重新寻一次路。
        //阶段3 开始攻击

        public bool isForceToEnd;
        private Vector3 lastTargetPosition;
        private UnitBase lastTarget;
        protected void UpdatePath()
        {
            var targetPosition = unit.Data.targetPosition;
            if (unit.Data.attackPosition != Vector3.zero)
            {
                targetPosition = unit.Data.attackPosition;
            }
            else if (unit.Data.lockTarget != null && !unit.Data.isGoingToHidePoint)
            {
                targetPosition = unit.Data.lockTarget.Data.position;
            }
            bool needRepath = false;
            bool needMove = false;
            bool needForceEnd = false;
            if (lastTargetPosition != targetPosition || unit.Data.lockTarget != lastTarget)
            {
                needRepath = !IsInRepathSuccessCD();
                if (unit.Data.lockTarget != lastTarget || unit.Data.isGoingToHidePoint || unit.Data.attackPosition != Vector3.zero)
                {
                    state = 0;
                    lastRepathTime = 0;
                }
            }
            lastTargetPosition = targetPosition;
            this.targetPosition = targetPosition;
            lastTarget = unit.Data.lockTarget;
            bool applyAstar = false;
            if (state == 0)
            {
                unit.Data.hasReachAttackPosition = false;
                if (State2Condition())
                {
                    state = 2;
                    if (PveFindPathManager.Instance.CheckIsWalkable(unit.Data.position, unit.Data.id) &&
                        State4Condition())
                    {
                        state = 4;
                        unit.Data.hasReachAttackPosition = true;
                    }
                }
                else if (!IsInRepathSuccessCD() && !IsInRepathFailCD())
                {
                    needRepath = true;
                    state = 1;
                    needMove = true;
                }
                else
                {
                    needMove = true;
                }
            }
            else if (state == 1)
            {
                needMove = true;
                if (State2Condition())
                {
                    state = 2;
                    needRepath = true;
                }
                else if (pathList.Count == 0)
                {
                    //if (!IsInRepathSuccessCD())
                    {
                        needRepath = true;
                        needForceEnd = true;
                        state = 2;
                    }
                }
            }
            else if (state == 2)
            {
                needMove = true;
                if (!PveFindPathManager.Instance.CheckIsWalkable(unit.Data.position, unit.Data.id))
                {
                    needRepath = true;
                }
                state = 3;
                applyAstar = true;
            }
            else if (state == 3)
            {
                if (!PveFindPathManager.Instance.CheckIsWalkable(unit.Data.position, unit.Data.id) && !IsInRepathFailCD())
                {
                    if (!IsInRepathSuccessCD())
                    {
                        needRepath = true;
                    }
                    else if (State4Condition())
                    {
                        state = 4;
                        unit.Data.hasReachAttackPosition = true;
                    }
                    needMove = true;
                }
                else if (State4Condition())
                {
                    state = 4;
                    unit.Data.hasReachAttackPosition = true;
                }
                else
                {
                    needMove = true;
                }

                if (pathList.Count == 0)
                {
                    needRepath = true;
                    needForceEnd = true;
                }

                applyAstar = true;
            }
            else if (state == 4)
            {
                if (!State4Condition())
                {
                    state = 0;
                }
                else
                {
                    applyAstar = true;
                }
                
            }

            if (unit.Data.isGoingToHidePoint || applyAstar)
            {
                unit.Data.AddAstar();
            }
            else
            {
                unit.Data.RemoveAstar();
            }

            if (needRepath)
            {
                bool isForceEnd = needForceEnd;
                if (forceEndCondition != null)
                {
                    isForceEnd = needForceEnd || forceEndCondition();
                }

                if (unit.Data.attackRange <= 1.6f)
                {
                    isForceEnd = true;
                }
                else if (!PveFindPathManager.Instance.CheckIsWalkable(unit.Data.position, unit.Data.id) && !unit.Data.isGoingToHidePoint)
                {
                    isForceEnd = false;
                }
                UpdateAStarPath(unit.Data.position,targetPosition,isForceEnd);
            }

            if (needMove)
            {
                UpdateRoadPath();
            }
            else
            {
                position = unit.Data.position;
            }
        }

        
        
        protected bool State2Condition()
        {
            if (condition2 != null)
            {
                return condition2();
            }
            if (unit.Data.lockTarget == null || unit.Data.lockTarget.Data.isDead)
            {
                return false;
            }
            return unit.Data.IsAttackInRange(1);
        }

        protected bool State4Condition()
        {
            return unit.Data.IsAttackInRange();
        }
        

        
        private bool IsInRepathFailCD()
        {
            if (isFindPathSuccess || lastFindPathFailTime == 0)
            {
                return false;
            }
            return TimeManager.logicTime - lastFindPathFailTime < 2;
        }

        private float repathCd = 0.5f;
        
        private bool IsInRepathSuccessCD()
        {
            if (!isFindPathSuccess)
            {
                return false;
            }
            return TimeManager.logicTime - lastRepathTime < repathCd;
        }
    }
}